/*
Java source file
Copyright: Umschalt.com 2011
*/
package com.david.documentation.service.parser;

import com.david.documentation.domain.entities.category.Category;
import com.david.documentation.domain.entities.doku.Doku;
import com.david.documentation.domain.entities.dokulinks.DokuLinks;
import com.david.documentation.domain.entities.episode.Episode;
import com.david.documentation.domain.entities.link.Link;
import com.david.documentation.domain.entities.tags.Tag;
import com.david.documentation.service.category.CategoryService;
import com.david.documentation.service.doku.DokuService;
import com.david.documentation.service.link.LinkService;
import com.david.documentation.service.tag.TagService;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.transaction.annotation.Transactional;

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Transactional(rollbackFor = Exception.class)
public class DokuJunkiesParserServiceImpl{

    private Document document;

	private DokuService dokuService;
	private LinkService linkService;
	private CategoryService categoryService;
	private TagService tagService;

	private static final String SERIENJUNKIES_URL ="http://dokujunkies.org/?cat=0&alldokus";
	private static final String SERIENJUNKIES_ALL_DOKUS_SELECTOR = "#sidebar #customList li a";
	private static final String SERIENJUNKIES_DOKU_SELECTOR = "#page_post";
	private static final String SERIENJUNKIES_DOKU_DETAIL_SELECTOR = ".post_details a";

	public DokuJunkiesParserServiceImpl(DokuService dokuService,LinkService linkService,CategoryService categoryService,TagService tagService){
		super();
		this.dokuService = dokuService;
		this.linkService = linkService;
		this.categoryService = categoryService;
		this.tagService = tagService;
	}

    public void parse(){
        try {
            URL url = new URL(SERIENJUNKIES_URL);
            document = Jsoup.parse(url, 8000);
            Elements elements = document.select(SERIENJUNKIES_ALL_DOKUS_SELECTOR);

			long startTime = System.currentTimeMillis();

			for (Element element : elements){
				Link link = new Link();
				link.setLink(element.attr("href"));

				if (!linkService.checkforDublicate(link.getLink())){

					try{
						document = Jsoup.connect(link.getLink()).ignoreContentType(true).get();
						Elements elem = document.select(SERIENJUNKIES_DOKU_SELECTOR);
						if (elem.get(0) != null){
							Doku doku = new Doku();

							MetaInfo metaInfo = getMetaInfoString(elem.get(0));
							doku.setName(getName(elem.get(0)));
							doku.setDescription(getDescription(elem.get(0)));
							doku.setImage_url(getImageUrl(elem.get(0)));

							doku.setDuration(metaInfo.getDuration());
							doku.setFormat(metaInfo.getFormat());
							doku.setLanguage(metaInfo.getLanguage());
							doku.setSize(metaInfo.getSize());
							doku.setUploader(metaInfo.getUploader());
							doku.setLink(link);
							doku.setDate(new Date());

							doku.setTags(getTags(document));
							doku.setCategorys(getCategorys(document));
							//doku.setDokuLinks(getDokuLinks(elem.get(0)));
							doku.setEpisodes(getEpisodes(elem.get(0)));

							dokuService.save(doku);
							System.out.println("DOKUINFOS GESPEICHERT - Anzahl der Episoden: " + doku.getEpisodes().size() + "( " + doku.getName() + " )");
						}
					}catch (Exception ex){
						System.out.println("FEHLER BEIM DOKUINFO SAMMELN: " + ex.getMessage());
					}
				} else{
					System.out.println("Doku gibts schon");
				}
			}
			long endTime = System.currentTimeMillis();
			System.out.println("ALLES FERTIG IN " + (endTime-startTime)/1000 + " Sekunden" );
        } catch (Exception e) {
            System.out.println("FEHLER BEIM LINKSAMMELN" + e.getMessage());
        }

    }

	private String getName(Element element){
		if (element.select("h2")!= null){
			return element.select("h2").text();
		}
		return "";
	}
	private String getDescription(Element element){
		String tmp = element.select("p").get(1).html();
		if (tmp.contains("<strong>Dauer:</strong>")){
			return element.select("p").get(2).text();
		}
		return element.select("p").get(1).text();
	}
	private String getImageUrl(Element element){
		if (element.select("p").size() > 0){
			return element.select("p").get(0).select("img").attr("src");
		}
		return "";
	}

	private MetaInfo getMetaInfoString(Element element){
		MetaInfo metaInfo = new MetaInfo();
		for (Element elem : element.select("p")){
			if (elem.html().contains("<strong>Dauer:</strong>")){
				String[] infos = elem.text().trim().split("\\|");
				metaInfo.duration = infos[0];
				metaInfo.size = infos[1];
				metaInfo.language = infos[2];
				metaInfo.format = infos[3];
				metaInfo.uploader = infos[4];
			}
		}
		return  metaInfo;
	}

	private List<Episode> getEpisodes(Element element){
		List<Episode> episodes = new ArrayList<Episode>();

		for (Element elem : element.select("p")){
			if (elem.html().contains("<strong>Download:</strong>")){
				List <DokuLinks> linksList = new ArrayList<DokuLinks>();
				for (Element e : elem.select("a")){
					linksList.add(new DokuLinks(e.attr("href"), StringUtils.replace(e.nextSibling().outerHtml(),"|","")));
				}
				episodes.add(new Episode(elem.select("strong").first().text(),linksList));
			}
		}
		return episodes;
	}

	private List<DokuLinks> getDokuLinks(Element element){
		List <DokuLinks> linksList = new ArrayList<DokuLinks>();
		for (Element elem : element.select("p")){
			if (elem.html().contains("<strong>Download:</strong>")){
				for (Element e : elem.select("a")){
					linksList.add(new DokuLinks(e.attr("href"), StringUtils.replace(e.nextSibling().outerHtml(),"|","")));
				}
			}
		}
		return linksList;
	}


	private List<Category> getCategorys(Document document){
		Elements elements = document.select(SERIENJUNKIES_DOKU_DETAIL_SELECTOR);
		elements.remove(0);

		List<Category> categoryList = new ArrayList<Category>();
		for (Element element : elements){
			if (element.attr("rel").contains("category")){
				if (categoryService.checkforDublicate(element.text())){
					categoryList.add(categoryService.findCategoryByName(element.text()));
				} else{
					categoryList.add(new Category(element.text()));
				}	
			}
		}
		return categoryList;
	}

	private List<Tag> getTags(Document document){
		Elements elements = document.select(SERIENJUNKIES_DOKU_DETAIL_SELECTOR);
		elements.remove(0);

		List<Tag> tagList = new ArrayList<Tag>();
		for (Element element : elements){
			if (element.attr("rel").contains("tag")){
				if (tagService.checkforDublicate(element.text())){
					tagList.add(tagService.findTagByName(element.text()));
				} else{
					tagList.add(new Tag(element.text()));
				}
			}
		}
		return tagList;
	}


	public class MetaInfo{

		private String duration;
		private String language;
		private String size;
		private String format;
		private String uploader;

		public String getDuration() {
			return duration;
		}

		public void setDuration(String duration) {
			this.duration = duration;
		}

		public String getLanguage() {
			return language;
		}

		public void setLanguage(String language) {
			this.language = language;
		}

		public String getSize() {
			return size;
		}

		public void setSize(String size) {
			this.size = size;
		}

		public String getFormat() {
			return format;
		}

		public void setFormat(String format) {
			this.format = format;
		}

		public String getUploader() {
			return uploader;
		}

		public void setUploader(String uploader) {
			this.uploader = uploader;
		}
	}


}
